package com.yj.ccs.abs.web.management.service;

import com.yj.ccs.abs.boot.pagination.Page;
import com.yj.ccs.abs.common.entity.Area;
import com.yj.ccs.abs.common.entity.Region;
import com.yj.ccs.abs.common.enums.AttachmentType;
import com.yj.ccs.abs.common.enums.CompanyNatureType;
import com.yj.ccs.abs.common.enums.ParentCompanyType;
import com.yj.ccs.abs.common.enums.ShadowRatingType;
import com.yj.ccs.abs.common.model.OaResponse;
import com.yj.ccs.abs.common.service.RegionService;
import com.yj.ccs.abs.oa.service.IntegrationService;
import com.yj.ccs.abs.web.common.entity.Attachment;
import com.yj.ccs.abs.web.common.mapper.AttachmentMapper;
import com.yj.ccs.abs.web.common.service.CommonService;
import com.yj.ccs.abs.web.management.dto.*;
import com.yj.ccs.abs.web.management.entity.Client;
import com.yj.ccs.abs.web.management.entity.ClientDetail;
import com.yj.ccs.abs.web.management.entity.ClientPageItem;
import com.yj.ccs.abs.web.management.entity.ParentCompany;
import com.yj.ccs.abs.web.management.mapper.ClientMapper;
import com.yj.ccs.abs.web.management.mapper.ManagementPageMapper;
import com.yj.ccs.abs.web.management.mapper.ParentCompanyMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Copyright 2018 (C) Yunjian-VC
 * Created on : 2018/3/16
 * Author     : Unbelievable9
 **/
@Service
public class ClientService {

    private static final Logger logger = LoggerFactory.getLogger(ClientService.class);

    private final ClientMapper clientMapper;

    private final ParentCompanyMapper parentCompanyMapper;

    private final ManagementPageMapper pageMapper;

    private final AttachmentMapper attachmentMapper;

    private final RegionService regionService;

    private final IntegrationService integrationService;

    private final CommonService commonService;

    @Autowired
    public ClientService(ClientMapper clientMapper,
                         ParentCompanyMapper parentCompanyMapper,
                         ManagementPageMapper pageMapper,
                         AttachmentMapper attachmentMapper,
                         RegionService regionService,
                         IntegrationService integrationService,
                         CommonService commonService) {
        this.clientMapper = clientMapper;
        this.parentCompanyMapper = parentCompanyMapper;
        this.pageMapper = pageMapper;
        this.attachmentMapper = attachmentMapper;
        this.regionService = regionService;
        this.integrationService = integrationService;
        this.commonService = commonService;
    }

    private Long createParentCompany(String name, CompanyNatureType nature, ParentCompanyType type) {
        ParentCompany parentCompany = new ParentCompany();
        parentCompany.setName(name);
        parentCompany.setNature(nature);
        parentCompany.setType(type);

        parentCompanyMapper.create(parentCompany);

        return parentCompany.getId();
    }

    private Boolean parentCompanyNameExistedForType(String name, ParentCompanyType type) {
        ParentCompany parentCompany = parentCompanyMapper.getByNameAndType(name, type.getValue());

        return parentCompany != null;
    }

    private String checkParentCompanyWhenCreate(Long id,
                                                String name,
                                                CompanyNatureType nature,
                                                ParentCompanyType type) {
        String error = null;
        String prefix;

        switch (type) {
            case PARENT:
                prefix = "母公司";

                break;
            case FINAL_PARENT:
                prefix = "终极母公司";

                break;
            default:
                prefix = "";
        }

        if (id == null) {
            if (!StringUtils.isEmpty(name)) {
                Boolean existed = parentCompanyNameExistedForType(name, type);

                if (existed) {
                    error = "公司名称已存在";
                } else {
                    if (nature == null) {
                        error = "信息填写不完整";
                    }
                }
            } else {
                error = "信息填写不完整";
            }

            if (error != null) {
                error = prefix + error;
            }
        }

        return error;
    }

    public Client getClientById(Long id) {
        return clientMapper.getById(id);
    }

    public Client getClientByName(String name) {
        return clientMapper.getByName(name);
    }

    public Page<ClientPageItem> getClientPage(KeywordDto keywordDto) {
        return pageMapper.getClientListOnCondition(keywordDto);
    }

    public List<ParentCompany> getParentCompanyList(ListParentDto listParentDto) {
        return parentCompanyMapper.getLatestByType(listParentDto.getType().getValue());
    }

    @Transactional
    public String createClient(CreateClientDto createClientDto) throws IOException {
        // 通知OA
        String oaResponseString = integrationService.addClient(createClientDto.getName());

        OaResponse<Map<String, Object>> response = integrationService.oaResponseDecode(oaResponseString, Map.class);

        if (response != null && response.getStatus() == 1) {
            Client client = new Client();
            BeanUtils.copyProperties(createClientDto, client);

            // 母公司、终极母公司 如果ID不存在则创建
            String parentError = checkParentCompanyWhenCreate(
                    createClientDto.getParent_id(),
                    createClientDto.getParent_name(),
                    createClientDto.getParent_nature(),
                    ParentCompanyType.PARENT);

            if (parentError != null) {
                return parentError;
            }

            String finalParentError = checkParentCompanyWhenCreate(
                    createClientDto.getFinal_parent_id(),
                    createClientDto.getFinal_parent_name(),
                    createClientDto.getFinal_parent_nature(),
                    ParentCompanyType.FINAL_PARENT);

            if (finalParentError != null) {
                return finalParentError;
            }

            if (client.getParent_id() == null) {
                client.setParent_id(createParentCompany(createClientDto.getParent_name(), createClientDto.getParent_nature(), ParentCompanyType.PARENT));
            }

            if (client.getFinal_parent_id() == null) {
                client.setFinal_parent_id(createParentCompany(createClientDto.getFinal_parent_name(), createClientDto.getFinal_parent_nature(), ParentCompanyType.FINAL_PARENT));
            }

            clientMapper.create(client);

            List<Attachment> combinedList = new ArrayList<>();

            if (createClientDto.getEquity() != null) {
                commonService.setupAttachmentList(createClientDto.getEquity(), client.getId(), AttachmentType.CLIENT_EQUITY);
                combinedList.addAll(createClientDto.getEquity());
            }

            if (createClientDto.getLicense() != null) {
                commonService.setupAttachmentList(createClientDto.getLicense(), client.getId(), AttachmentType.CLIENT_LICENSE);
                combinedList.addAll(createClientDto.getLicense());
            }

            if (combinedList.size() > 0) {
                attachmentMapper.batchCreate(combinedList);
            }

            return null;
        } else {
            return "企业客户信息推送到OA失败, 无法创建";
        }
    }

    public ClientDetail getClientDetail(Client client) {
        ClientDetail clientDetail = new ClientDetail();
        BeanUtils.copyProperties(client, clientDetail);
        clientDetail.setNature(CompanyNatureType.fromValue(client.getNature().getValue()));
        clientDetail.setShadow_rating(ShadowRatingType.fromValue(client.getShadow_rating().getValue()));
        clientDetail.setEquity(attachmentMapper.getByIdAndType(client.getId(), AttachmentType.CLIENT_EQUITY.getValue()));
        clientDetail.setLicense(attachmentMapper.getByIdAndType(client.getId(), AttachmentType.CLIENT_LICENSE.getValue()));

        Area area = regionService.getAreaByCode(clientDetail.getArea_code());
        Region region = regionService.getRegionByAreaCode(area.getCode());

        clientDetail.setArea_name(region.getArea_name());
        clientDetail.setCity_code(area.getCityCode());
        clientDetail.setCity_name(region.getCity_name());
        clientDetail.setProvince_code(area.getProvinceCode());
        clientDetail.setProvince_name(region.getProvince_name());

        ParentCompany parentCompany = parentCompanyMapper.getById(client.getParent_id());
        ParentCompany finalParentCompany = parentCompanyMapper.getById(client.getFinal_parent_id());

        if (parentCompany != null) {
            clientDetail.setParent_name(parentCompany.getName());
            clientDetail.setParent_nature(parentCompany.getNature());
        }

        if (finalParentCompany != null) {
            clientDetail.setFinal_parent_name(finalParentCompany.getName());
            clientDetail.setFinal_parent_nature(finalParentCompany.getNature());
        }

        return clientDetail;
    }

    @Transactional
    public String updateClient(UpdateClientDto updateClientDto) {
        Client client = new Client();
        BeanUtils.copyProperties(updateClientDto, client);

        // 母公司、终极母公司 如果ID不存在则创建
        String parentError = checkParentCompanyWhenCreate(
                updateClientDto.getParent_id(),
                updateClientDto.getParent_name(),
                updateClientDto.getParent_nature(),
                ParentCompanyType.PARENT);

        if (parentError != null) {
            return parentError;
        }

        String finalParentError = checkParentCompanyWhenCreate(
                updateClientDto.getFinal_parent_id(),
                updateClientDto.getFinal_parent_name(),
                updateClientDto.getFinal_parent_nature(),
                ParentCompanyType.FINAL_PARENT);

        if (finalParentError != null) {
            return finalParentError;
        }

        if (client.getParent_id() == null) {
            client.setParent_id(createParentCompany(updateClientDto.getParent_name(), updateClientDto.getParent_nature(), ParentCompanyType.PARENT));
        }

        if (client.getFinal_parent_id() == null) {
            client.setFinal_parent_id(createParentCompany(updateClientDto.getFinal_parent_name(), updateClientDto.getFinal_parent_nature(), ParentCompanyType.FINAL_PARENT));
        }

        clientMapper.update(client);

        // 股权关系
        attachmentMapper.deleteByIdAndType(client.getId(), AttachmentType.CLIENT_EQUITY.getValue());

        if (updateClientDto.getEquity() != null) {
            commonService.setupAttachmentList(updateClientDto.getEquity(), client.getId(), AttachmentType.CLIENT_EQUITY);
            attachmentMapper.batchCreate(updateClientDto.getEquity());
        }

        // 营业执照
        attachmentMapper.deleteByIdAndType(client.getId(), AttachmentType.CLIENT_LICENSE.getValue());

        if (updateClientDto.getLicense() != null) {
            commonService.setupAttachmentList(updateClientDto.getLicense(), client.getId(), AttachmentType.CLIENT_LICENSE);
            attachmentMapper.batchCreate(updateClientDto.getLicense());
        }

        return null;
    }

    @Transactional
    public void deleteClient(IdListDto idListDto) {
        clientMapper.batchDelete(idListDto);

        attachmentMapper.batchDeleteByIdsAndType(idListDto, AttachmentType.CLIENT_EQUITY.getValue());
        attachmentMapper.batchDeleteByIdsAndType(idListDto, AttachmentType.CLIENT_LICENSE.getValue());
    }
}
